﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <stdio.h>
#include <string>
#include "detours.h"
#include "taskCall.h"



WebSocketClient* g_client = NULL;
typedef __int64(__fastcall* Tick_fun)(__int64 a1);
static Tick_fun Tick_old{};
DWORD g_mainThreadId{};

bool OnReceiveProtocolMessage(WebSocketClient* pClient , int protocolId, int requestId, const msgpack::v2::object* objects, uint32_t objectCount);
void OnMessage(WebSocketClient* pClient , const char* buf, size_t len);




int g_updateInterval = 3; // 每？帧更新一次  
int g_frameCounter = 0; // 帧计数器  
__int64 __fastcall Tick_new(__int64 a1)
{


    // 更新帧计数器  
    g_frameCounter++;
    // 检查是否达到更新间隔  
    if (g_frameCounter >= g_updateInterval)
    {

        g_GameData.Update();

       
        g_frameCounter = 0; // 重置计数器  
    }

    auto call = g_GameData.GetCall();
    if (call)
    {
        call->UseCall();
    }

    return Tick_old(a1);
}

std::string FormatString(const char* fmt, ...) {
    // ����һ���㹻��Ļ��������洢��ʽ������ַ���  
    // ����Ը���ʵ����Ҫ�����������Ĵ�С  
    const size_t bufferSize = 1024;
    char buffer[bufferSize];


    // ��ʼ��va_list  
    va_list args;
    va_start(args, fmt);


    // ʹ��vsnprintf����ʽ������ַ���д�뻺����  
    // ע�⣺����ʹ��bufferSize - 1��ȷ�����������������������һ��λ�ø�'\0'  
    vsnprintf(buffer, bufferSize - 1, fmt, args);


    // ����va_list��ʹ��  
    va_end(args);


    // ���������е��ַ���ת��Ϊstd::string������  
    return std::string(buffer);
}
#include <sstream>

// 将特征字符串转换为字节数组
std::vector<uint8_t> ParsePattern(const std::string& pattern) {
    std::vector<uint8_t> bytes;
    std::istringstream ss(pattern);
    std::string byte;

    while (ss >> byte) {
        if (byte == "??") {
            bytes.push_back(0x00); // 用于通配符
        }
        else {
            bytes.push_back(static_cast<uint8_t>(std::stoul(byte, nullptr, 16)));
        }
    }

    return bytes;
}

// 在内存中查找模式
uintptr_t FindPattern(const std::string& moduleName, const std::string& pattern) {
    // 获取模块句柄
    HMODULE hModule = GetModuleHandleA(moduleName.c_str());
    if (!hModule) {
        //std::cerr << "Failed to get module handle!" << std::endl;
        return 0;
    }

    // 获取模块的基地址
    uintptr_t baseAddress = reinterpret_cast<uintptr_t>(hModule);

    // 解析模式
    std::vector<uint8_t> patternBytes = ParsePattern(pattern);
    size_t patternSize = patternBytes.size();

    // 假设模块的大小是 0x100000（可以根据需要调整）
    const size_t moduleSize = 0x100000; // 例如，假设模块最大为 1MB

    // 遍历内存查找匹配
    for (uintptr_t i = baseAddress; i < baseAddress + moduleSize - patternSize; ++i) {
        bool found = true;

        for (size_t j = 0; j < patternSize; ++j) {
            // 检查字节是否匹配或是通配符
            if (patternBytes[j] != 0x00 && *reinterpret_cast<uint8_t*>(i + j) != patternBytes[j]) {
                found = false;
                break;
            }
        }

        if (found) {
            return i; // 返回匹配的地址
        }
    }

    return 0; // 未找到
}

#include "d3d11.h"
#include "dxgi.h"

using Present_t = HRESULT(STDMETHODCALLTYPE*)(IDXGISwapChain* This, UINT SyncInterval, UINT Flags);
Present_t originalPresent{};



//////////////////////////////////////////////////////////////////////////
//::cocos2d_GLViewImpl_windowShouldClose
typedef BOOL(WINAPI* QueryPerformanceCounter_fun)(_Out_ LARGE_INTEGER* lpPerformanceCount);
static QueryPerformanceCounter_fun QueryPerformanceCounter_old = QueryPerformanceCounter;


//////////////////////////////////////////////////////////////////////////
//RtlExitUserThread
typedef VOID(WINAPI* TRtlExitUserThread)(DWORD code);
static TRtlExitUserThread RtlExitUserThread_old = 0;
static VOID WINAPI RtlExitUserThread_new(DWORD code);


//////////////////////////////////////////////////////////////////////////
//WaitForSingleObject
typedef DWORD(WINAPI* TWaitForSingleObject)(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
    );

static TWaitForSingleObject  WaitForSingleObject_old = ::WaitForSingleObject;
#include <intrin.h>
std::mutex g_mutex;
DWORD socketThreadId = 0;
bool g_hookIsInti = 0;
bool isSteamHook = 0;
static DWORD WINAPI WaitForSingleObject_new(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
)
{
   
    

    if (!g_hookIsInti)
    {
        {
                
            size_t vtptr = GameCore_read<size_t>(GameCore_GetGameBaseAddress() + GameOffset_GDynamicRHI);
            if (vtptr)
            {
                char* vt_new = new char[0x1000];
                OutputDebugStringA(FormatString("fs: vtptr : %llx \n", vtptr).c_str());
                size_t vtAdd = GameCore_read<size_t>(vtptr);
                if (vtAdd && GameCore_read<size_t>(vtAdd + 0x3e8))
                {
                    memcpy(vt_new, (char*)vtAdd, 0x1000);
                    Tick_old = (Tick_fun)(*((size_t*)(vtAdd + 0x3e8)));
                    *((size_t*)(vt_new + 0x3e8)) = (size_t)Tick_new;
                    *((size_t*)vtptr) = (size_t)vt_new;
                    OutputDebugStringA(FormatString("fs: vt_new:%p Tick_old:%p\n", vt_new, Tick_old).c_str());


                    g_hookIsInti = true;
                }
            }
        }
                
    }
         


    return WaitForSingleObject_old(hHandle, dwMilliseconds);
}


// 线程函数
size_t SocketThreadFunc_time = 0;
DWORD WINAPI SocketThreadFunc(LPVOID lpParam)
{
    DEBUG_INFO_OUTPUT("fs:线程正在运行...\n");

    while (true)
    {
        if (!g_client)
        {
            g_client = new WebSocketClient("ws://localhost:8888/websocket");
            g_client->setOnMessage(OnMessage);
            g_client->connect();
            g_client->WaitForConnection(3000);

        }
        if (g_client)
        {

            if (!g_client->isConnected())
            {
                DEBUG_INFO_OUTPUT("fs:开始连接服务器");
                g_client->connect();
                g_client->WaitForConnection(3000);
            }



            g_client->pool();
        }

        if (g_client && g_client->isConnected())
        {
            {
                g_GameData.SendRangeActors(g_client);
                g_GameData.SendQuickSlot(g_client);
            }

        }

        Sleep(20);
    }
    return 0;
}

//////////////////////////////////////////////////////////////////////////
//::cocos2d_GLViewImpl_windowShouldClose
typedef VOID(WINAPI* BaseThreadInitThunk_fun)(IN DWORD LdrReserved, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter);
static BaseThreadInitThunk_fun BaseThreadInitThunk_old = 0;
//std::mutex BaseThreadInitThunk_mutex ;
VOID WINAPI BaseThreadInitThunk_new(IN DWORD LdrReserved, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter)
{
    //std::lock_guard<std::mutex> lock(BaseThreadInitThunk_mutex);
    if ((size_t)lpParameter == 0x159357)
    {
        DEBUG_INFO_OUTPUT("fs:BaseThreadInitThunk_new");
        lpStartAddress = (LPTHREAD_START_ROUTINE)SocketThreadFunc;
        //开始事务
        //DetourTransactionBegin();
        //更新线程信息 
        //DetourUpdateThread(GetCurrentThread());
        //将拦截的函数从原函数的地址上解除，这里可以解除多个函数。
        //DetourDetach(&(PVOID&)BaseThreadInitThunk_old, BaseThreadInitThunk_new);
        //结束事务
        //DetourTransactionCommit();
    }
    BaseThreadInitThunk_old(LdrReserved, lpStartAddress, lpParameter);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        HMODULE kernel32_dll = GetModuleHandleA("kernel32.dll");
        BaseThreadInitThunk_old = (BaseThreadInitThunk_fun)GetProcAddress(kernel32_dll, "BaseThreadInitThunk");
        DEBUG_INFO_OUTPUT("fs:BaseThreadStart : %llx\n", BaseThreadInitThunk_old);

        DEBUG_INFO_OUTPUT("fs:DllMain 1");

        size_t gameoverlayrenderer64_dll = (size_t)GetModuleHandleA("gameoverlayrenderer64.dll");



       
        //开始detours事务
        DetourTransactionBegin();
        DetourAttach(&(PVOID&)WaitForSingleObject_old, WaitForSingleObject_new);
        DetourAttach(&(PVOID&)BaseThreadInitThunk_old, BaseThreadInitThunk_new);
        DetourTransactionCommit();

        

        
        DEBUG_INFO_OUTPUT("fs:开始创建线程");
        // 创建线程
        HANDLE hThread = CreateThread(
            NULL,           // 默认安全属性
            0,              // 默认堆栈大小
            (LPTHREAD_START_ROUTINE)((LPTHREAD_START_ROUTINE)(GameCore_GetGameBaseAddress() + 0x32458)),     // 线程函数地址
            (LPVOID)0x159357,           // 传递给线程函数的参数
            0,              // 创建后立即运行
            NULL            // 不需要返回线程ID
        );

        if (hThread == NULL)
        {
            DEBUG_INFO_OUTPUT("创建线程失败，错误代码: %d\n", GetLastError());
            return 1;
        }
        else
        {
            DEBUG_INFO_OUTPUT("fs:创建线程结束");
        }

    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

void OnInvalidParameterRequest(WebSocketClient* pClient, int protocolId, int requestId)
{
    // 序列化  
    msgpack::sbuffer sbuf;
    // 创建一个 packer，用于向 sbuf 中打包数据  
    msgpack::packer<msgpack::sbuffer> pk(sbuf);

    pk.pack_array(3);
    pk.pack((uint32_t)protocolId - NetworkProtocol::AFAPI::ServerToClient::RequestFailure);
    pk.pack((uint32_t)requestId);
    pk.pack((uint32_t)STATUS_INVALID_PARAMETER);

    pClient->SendBinary(sbuf.data(), sbuf.size());
}

#define READ_ULONG64_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::POSITIVE_INTEGER && objects[index].type != msgpack::type::NEGATIVE_INTEGER){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<ULONG64>();

#define READ_ULONG_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::POSITIVE_INTEGER && objects[index].type != msgpack::type::NEGATIVE_INTEGER ){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<ULONG>();

#define READ_INT_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::POSITIVE_INTEGER && objects[index].type != msgpack::type::NEGATIVE_INTEGER){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<int>();

#define READ_UINT32_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::POSITIVE_INTEGER && objects[index].type != msgpack::type::NEGATIVE_INTEGER){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<UINT32>();

#define READ_UINT64_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::POSITIVE_INTEGER && objects[index].type != msgpack::type::NEGATIVE_INTEGER){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<UINT64>();

#define READ_BOOL_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::BOOLEAN){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<bool>();

#define READ_FLOAT_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::FLOAT32 && objects[index].type != msgpack::type::FLOAT64){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<float>();

#define READ_DOUBLE_FROM_MSGPACK_OBJECT(name, index) \
	if (objects[index].type != msgpack::type::FLOAT32 && objects[index].type != msgpack::type::FLOAT64){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].as<double>();

#define READ_BINARY_FROM_MSGPACK_OBJECT(name, nameSize, index) \
	if (objects[index].type != msgpack::type::BIN){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].via.bin.ptr;\
	auto nameSize = objects[index].via.bin.size;

#define READ_STRING_FROM_MSGPACK_OBJECT(name, nameLength, index) \
	if (objects[index].type != msgpack::type::STR){\
		DEBUG_INFO_OUTPUT(skCrypt("OnReceiveProtocolMessage %d %d failed! element[%d].type == %d\n"), protocolId, requestId, index, objects[index].type);\
		OnInvalidParameterRequest(pClient, protocolId, requestId);\
		return false;\
	}\
	auto name = objects[index].via.str.ptr;\
	auto nameLength = objects[index].via.str.size;

void OnMessage(WebSocketClient* pClient , const char* buf, size_t len)
{
    DEBUG_INFO_OUTPUT("fs:OnMessage");
    // 设定解包的初始位置  
    msgpack::object_handle oh = msgpack::unpack(buf, len);

    // 获取解包后的对象  
    msgpack::object object = oh.get();
    // 检查顶层是否是一个数组  
    if (object.type != msgpack::type::ARRAY) {
        return;
    }
    int protocolId = object.via.array.ptr[0].as<int>();
    int requestId = object.via.array.ptr[1].as<int>();
    OnReceiveProtocolMessage(pClient, protocolId, requestId, object.via.array.ptr + 2, object.via.array.size - 2);
}

bool OnScriptAPISelectObjRequest(WebSocketClient* pClient, int protocolId, int requestId, const UINT32 id)
{
    UINT32 st = 0;
    if (g_TLTargetHelper) {
        GameCore_write<UINT32>(g_TLTargetHelper + SelectObj_OFFSET, id);
        st = 1;
    }
    else {
        st = 0;
    }

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)st);

        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return false;
}

bool OnScriptAPIFacingCoordinatesRequest(WebSocketClient* pClient, int protocolId, int requestId, const TLPoint& p)
{
    std::shared_ptr<CFacingCoordinates> call(new CFacingCoordinates(p));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer sbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(sbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        pClient->SendBinary(sbuf.data(), sbuf.size());
    }

    return true;
}

bool OnScriptAPIAreaTeleportRequest(WebSocketClient* pClient, int protocolId, int requestId, UINT64 areaId)
{
    std::shared_ptr<CAreaTeleport> call(new CAreaTeleport(areaId));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);
        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPISpecifyTasksRequest(WebSocketClient* pClient, int protocolId, int requestId, const UINT32 type)
{

    std::shared_ptr<CGetTasks> call(new CGetTasks(type));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    if (pClient)
    {
        g_GameData.SendTaskAdventureExploration(pClient, requestId, call->m_tasks);
    }
    return true;
}

bool OnScriptAPIUseEquipmentRequest(WebSocketClient* pClient, int protocolId, int requestId, const UINT64 id, const UINT32 index)
{
    std::shared_ptr<CUseEquipment> call(new CUseEquipment(id , index));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);
        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIFindSWidgetRequest(WebSocketClient* pClient, int protocolId, int requestId, const std::string& text)
{
    std::shared_ptr<CFindSWidget> call(new CFindSWidget(text));
    g_GameData.AddCall(call.get());
    call->Wait(5000);

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(8);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        packer.pack(call->m_bFound);
        packer.pack(call->m_rect.x);
        packer.pack(call->m_rect.y);
        packer.pack(call->m_rect.width);
        packer.pack(call->m_rect.height);
        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIUpdateTeleportPointRequest(WebSocketClient* pClient, int protocolId, int requestId)
{
    std::shared_ptr<CUpdateTeleportPoint> call(new CUpdateTeleportPoint());
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(4);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        packer.pack(call->m_TeleportPoints);

        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIUpdateSkillsRequest(WebSocketClient* pClient, int protocolId, int requestId)
{
    std::shared_ptr<CUpdateSkill> call(new CUpdateSkill());
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    
    for (auto v : call->m_skills)
    {
        UtilUnicodeToUTF8(v->m_name, v->m_name_utf8);
    }

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(4);
        packer.pack((uint32_t)NetworkProtocol::AFAPI::ServerToClient::ScriptAPIFinAPIUpdateSkillsResponse);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        packer.pack(call->m_skills);

        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }

    return true;
}

bool OnScriptAPIUseConsumable(WebSocketClient* pClient, int protocolId, int requestId, UINT64 itemID, int itemID2, int destID, float destX, float destY, float destZ)
{
    std::shared_ptr<CUseConsumable> call(new CUseConsumable(itemID,  itemID2,  destID,  destX,  destY,  destZ));
    g_GameData.AddCall(call.get());
    call->Wait(5000);

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);


        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIUseConsumableWithQuantity(WebSocketClient* pClient, int protocolId, int requestId, UINT64 itemID, int sum)
{
    std::shared_ptr<CUseConsumableWithQuantity> call(new CUseConsumableWithQuantity(itemID, sum));
    g_GameData.AddCall(call.get());
    call->Wait(5000);

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);


        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIOngoingSchedule(WebSocketClient* pClient, int protocolId, int requestId)
{
    std::shared_ptr<CUpdateSchedule> call(new CUpdateSchedule());
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        for (auto v : call->m_SSchedules)
        {
            UtilUnicodeToUTF8(v->name, v->name_utf8);
            UtilUnicodeToUTF8(v->description, v->description_utf8);
        }

        packer.pack_array(4);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        packer.pack(call->m_SSchedules);


        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIInteractive(WebSocketClient* pClient, int protocolId, int requestId, UINT64 actor_id)
{
    std::shared_ptr<CInteractive> call(new CInteractive(actor_id));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);



        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);



        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIMovToActor(WebSocketClient* pClient, int protocolId, int requestId, UINT64 actor_id)
{
    std::shared_ptr<CMovToActor> call(new CMovToActor(actor_id));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
  
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);



        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);



        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPISetCharacterName(WebSocketClient* pClient, int protocolId, int requestId, std::string& name)
{
    std::shared_ptr<CSetCharacterName> call(new CSetCharacterName(name));
    g_GameData.AddCall(call.get());
    call->Wait(5000);
    
    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);



        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);



        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

bool OnScriptAPIGetInventory(WebSocketClient* pClient, int protocolId, int requestId)
{
    std::shared_ptr<CGetInventory> call(new CGetInventory());
    g_GameData.AddCall(call.get());
    call->Wait(5000);

    if (pClient)
    {

        for (auto v : call->m_items)
        {
            UtilUnicodeToUTF8(v->m_name , v->m_name_utf8);
        }
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);



        packer.pack_array(4);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);

        packer.pack(call->m_items);


        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    
    return true;
}



bool OnReceiveProtocolMessage(WebSocketClient* pClient, int protocolId, int requestId, const msgpack::v2::object* objects, uint32_t objectCount)
{
    DEBUG_INFO_OUTPUT("fs: protocolId:%d requestId:%d objectCount;%d" , protocolId , requestId , objectCount);

    switch (protocolId)
    {
        //改朝向
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIFacingCoordinatesRequest:
    {
        if (objectCount < 3)
            return false;

        READ_FLOAT_FROM_MSGPACK_OBJECT(x, 0);
        READ_FLOAT_FROM_MSGPACK_OBJECT(y, 1);
        READ_FLOAT_FROM_MSGPACK_OBJECT(z, 2);

        TLPoint p(x , y , z);
        return OnScriptAPIFacingCoordinatesRequest(pClient, protocolId, requestId, p);
    }
        //选择对象
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPISelectObjRequest:
    {
        if (objectCount < 1)
            return false;

        READ_UINT32_FROM_MSGPACK_OBJECT(objID, 0);

        return OnScriptAPISelectObjRequest(pClient, protocolId, requestId, objID);
    }
    //区域传送
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIAreaTeleportRequest:
    {
        if (objectCount < 1)
            return false;

        READ_UINT64_FROM_MSGPACK_OBJECT(areaID, 0);

        return OnScriptAPIAreaTeleportRequest(pClient, protocolId, requestId, areaID);
    }
    //取指定任务信息
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPISpecifyTasksRequest:
    {
        if (objectCount < 1)
            return false;

        READ_UINT32_FROM_MSGPACK_OBJECT(type, 0);

        return OnScriptAPISpecifyTasksRequest(pClient, protocolId, requestId, type);
    }
    //穿戴装备.
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIUseEquipmentRequest:
    {
        if (objectCount < 2)
            return false;

        READ_UINT64_FROM_MSGPACK_OBJECT(id, 0);
        READ_UINT32_FROM_MSGPACK_OBJECT(index, 1);
        return OnScriptAPIUseEquipmentRequest(pClient, protocolId, requestId, id, index);
    }
    //查找UI控件
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIFindSWidgetRequest:
    {
        if (objectCount < 1)
            return false;

        READ_STRING_FROM_MSGPACK_OBJECT(name, nameLength, 0);

        std::string text(name, nameLength);

        return OnScriptAPIFindSWidgetRequest(pClient, protocolId, requestId, text);
    }
    //遍历传送点..
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIUpdateTeleportPointRequest:
    {
        return OnScriptAPIUpdateTeleportPointRequest(pClient, protocolId, requestId);
    }
    //遍历技能
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIUpdateSkillsRequest:
    {
        return OnScriptAPIUpdateSkillsRequest(pClient, protocolId, requestId);
    }
    //使用消耗品
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIItemUsageRequest:
    {
        READ_UINT64_FROM_MSGPACK_OBJECT(itemID, 0);
        READ_INT_FROM_MSGPACK_OBJECT(itemID2, 1);
        READ_INT_FROM_MSGPACK_OBJECT(destID, 2);
        READ_FLOAT_FROM_MSGPACK_OBJECT(destX, 3);
        READ_FLOAT_FROM_MSGPACK_OBJECT(destY, 4);
        READ_FLOAT_FROM_MSGPACK_OBJECT(destZ, 5);
        return OnScriptAPIUseConsumable(pClient, protocolId, requestId, itemID, itemID2, destID, destX, destY, destZ);
    }
    //使用消耗品2
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIUseConsumableWithQuantityRequest:
    {
        READ_UINT64_FROM_MSGPACK_OBJECT(itemID, 0);
        READ_INT_FROM_MSGPACK_OBJECT(sum, 1);
        return OnScriptAPIUseConsumableWithQuantity(pClient, protocolId, requestId, itemID, sum);
    }

    //遍历正在进行日程
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIOngoingScheduleRequest:
    {
        return OnScriptAPIOngoingSchedule(pClient, protocolId, requestId);
    }

    //交互
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIInteractiveRequest:
    {
        READ_UINT64_FROM_MSGPACK_OBJECT(actor_id, 0);
        return OnScriptAPIInteractive(pClient, protocolId, requestId, actor_id);
    }

    //移动到对象
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIMovToActorRequest:
    {
        if (objectCount < 1)
            return false;
        READ_UINT64_FROM_MSGPACK_OBJECT(actor_id, 0);
        return OnScriptAPIMovToActor(pClient, protocolId, requestId, actor_id);
    }
    //新手剧情取名
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPISetCharacterNameRequest:
    {
        if (objectCount < 1)
            return false;

        READ_STRING_FROM_MSGPACK_OBJECT(name, nameLength, 0);
        std::string text(name, nameLength);
        return OnScriptAPISetCharacterName(pClient, protocolId, requestId, text);
    }
    //获取背包数据
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIGetInventoryRequest:
    {

        return OnScriptAPIGetInventory(pClient, protocolId, requestId);
    }
    //移动至坐标
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIMoveToRequest:
    {
        if (objectCount < 3)
            return false;

        READ_FLOAT_FROM_MSGPACK_OBJECT(x, 0);
        READ_FLOAT_FROM_MSGPACK_OBJECT(y, 1);
        READ_FLOAT_FROM_MSGPACK_OBJECT(z, 2);
        GameCore_MoveTo(x , y , z);
        break;
    }
    //自动前进
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIToggleKeepMoveForwardRequest:
    {
        std::shared_ptr<CToggleKeepMoveForward> call(new CToggleKeepMoveForward());
        g_GameData.AddCall(call.get());
        call->Wait(5000);
        break;
    }
    //鼠标点击
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIMouseClickRequest:
    {
        if (objectCount < 4)
            return false;

        READ_INT_FROM_MSGPACK_OBJECT(hwnd, 0);
        READ_INT_FROM_MSGPACK_OBJECT(x, 1);
        READ_INT_FROM_MSGPACK_OBJECT(y, 2);
        READ_INT_FROM_MSGPACK_OBJECT(mode, 3);
        GameCore_MouseClick(hwnd , x , y , mode);

        break;
    }
    //按键
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIExecuteKeyPressRequest:
    {
        if (objectCount < 3)
            return false;

        READ_INT_FROM_MSGPACK_OBJECT(hwnd, 0);
        READ_INT_FROM_MSGPACK_OBJECT(key, 1);
        READ_INT_FROM_MSGPACK_OBJECT(mode, 2);
        GameCore_ExecuteKeyPress(hwnd, key, mode);

        break;
    }
    //组队邀请
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIInviteToTeamRequest:
    {
        if (objectCount < 1)
            break;

        READ_STRING_FROM_MSGPACK_OBJECT(nameptr, nameLength, 0);
        std::string name(nameptr, nameLength);
        std::shared_ptr<CInviteToTeam> call(new CInviteToTeam(name));
        g_GameData.AddCall(call.get());
        call->Wait(5000);
        break;
    }
    //传送_士兵娃娃之家
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPITeleport_sbwwRequest:
    {

        std::shared_ptr<CTeleport_sbww> call(new CTeleport_sbww());
        g_GameData.AddCall(call.get());
        call->Wait(5000);
        break;
    }
    //获取队伍信息
    case NetworkProtocol::AFAPI::ClientToServer::ScriptAPIUpdatePartyInfoRequest:
    {

        std::shared_ptr<CGetPartyInfo> call(new CGetPartyInfo());
        g_GameData.AddCall(call.get());
        call->Wait(5000);
        DEBUG_INFO_OUTPUT("fs: m_partyInfoS:%d" , call->m_partyInfoS.size());
        {
            // 序列化  
            msgpack::sbuffer m_sendbuf;
            // 创建一个 packer，用于向 sbuf 中打包数据  
            msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

            packer.pack_array(4);
            packer.pack((uint32_t)0);
            packer.pack((uint32_t)requestId);
            packer.pack((uint32_t)0);
            packer.pack(call->m_partyInfoS);

            pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
        }
        return true;
    }
    
    
    }

    if (pClient)
    {
        // 序列化  
        msgpack::sbuffer m_sendbuf;
        // 创建一个 packer，用于向 sbuf 中打包数据  
        msgpack::packer<msgpack::sbuffer> packer(m_sendbuf);

        packer.pack_array(3);
        packer.pack((uint32_t)0);
        packer.pack((uint32_t)requestId);
        packer.pack((uint32_t)0);
        pClient->SendBinary(m_sendbuf.data(), m_sendbuf.size());
    }
    return true;
}

